package com.rich.live.service.impl;

import com.rich.common.entity.TbBroker;
import com.rich.common.result.CommonResponse;
import com.rich.common.result.ResultData;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rich.common.util.JwtUtil;
import com.rich.live.mapper.LiveFollowerMapper;
import com.rich.live.mapper.LiveMapper;
import com.rich.live.pojo.TbLive;
import com.rich.live.service.LiveService;
import com.rich.live.thread.RecordVideoThread;
import com.rich.live.vo.LiveVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author hu
 * @version 1.0
 * @date 2021/08/14 18:51
 */
@Service
public class LiveServiceImpl implements LiveService {

    @Autowired
    private LiveMapper liveMapper;

    @Autowired
    private LiveFollowerMapper liveFollowerMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 分页+模糊查询
     *
     * @param  liveVo
     * @return ResultData
     */
    @Override
    public ResultData liveList(LiveVo liveVo) {
        PageHelper.startPage(liveVo.getPage(), liveVo.getLimit());
        List<TbLive> tbLives = liveMapper.selectByExample(liveVo);
        PageInfo<TbLive> pageInfo = new PageInfo<>(tbLives);
        return new ResultData(pageInfo.getList(), pageInfo.getTotal());
    }

    /**
     * 创建直播
     *
     * @param live
     * @param token
     */
    @Override
    public void addLive(TbLive live,String token) {
        String s = JwtUtil.parseToken(token);
        TbBroker broker = (TbBroker) redisTemplate.opsForValue().get(s);
        live.setBid(Long.valueOf(broker.getId()));
        live.setBrokerName(broker.getBrokerName());
        live.setStartTime(new Date());
        live.setStatus("0");
        live.setLikeNum(0);
        live.setAttentionNum(0);
        live.setLookNum(0);
        live.setCreateTime(new Date());
        live.setIsDelete("0");
        live.setRole("1");
        live.setViolation("0");
        live.setPlayBack("0");
        live.setPlayNum(0);
        live.setPushStream("rtmp://10.3.176.26:1935/live/");
        live.setPullStream("rtmp://10.3.176.26/live/" + live.getBid());
        liveMapper.addLive(live);
    }


    /**
     * 开启关闭直播
     *
     * @param id
     * @param violation
     */
    @Override
    public void onAndOff(Long id, String violation) {
        liveMapper.onAndOff(id, violation);
    }

    /**
     * 当前直播人和在线人数
     * @param id
     * @return
     */
    @Override
    public CommonResponse liveDetails(Long id) {
        return liveMapper.liveDetails(id);
    }

    /**
     * 退出直播间 在线人数+1
     *
     * @param id
     */
    @Override
    public void liveInfo(Long id) {
        liveMapper.liveInfo(id);
    }

    /**
     * 退出直播间 在线人数-1
     *
     * @param id
     */
    @Override
    public void liveExit(Long id) {
        liveMapper.liveExit(id);
    }

    /**
     * 查询当前直播信息
     *
     * @param id
     * @return
     */
    @Override
    public TbLive findOne(Long id) {
        return liveMapper.findOne(id);
    }

    /**
     * 逻辑删除
     *
     * @param id
     */
    @Override
    public void deleteById(Long id) {
        liveMapper.deleteById(id);
        liveFollowerMapper.deleteById(id);
    }

    /**
     * 拉流
     * @param id
     * @return
     */
    @Override
    public CommonResponse la(Long id) {
        return liveMapper.la(id);
    }

    /**
     * 不限、正在直播、精彩回放查询
     *
     * @param status
     * @return
     */
    @Override
    public List<TbLive> allLive(String status) {
        return liveMapper.allLive(status);
    }

    /**
     * 精彩回放点击量
     * @param id
     */
    @Override
    public void updatePlayNum(Long id) {
        liveMapper.updatePlayNum(id);
    }

    /**
     * 开启直播
     *
     * @param id
     * @return
     */
    @Override
    public TbLive start(Long id) {
        TbLive live = liveMapper.findOne(id);
        //开启直播录制
        playback(live);
        return live;
    }

    /**
     * 开启直播录制
     * @param live
     */
    @Async
    public void playback(TbLive live){

        RecordVideoThread thread = new RecordVideoThread();
        //线程名称
        thread.setName(live.getBrokerName());
        //视频保存地址
        thread.setFilePath("D:/image/TV/"+live.getBrokerName()+ UUID.randomUUID().toString()+".flv");
        //设置流地址
        thread.setStreamUrl(live.getPushStream()+live.getBid());
        liveMapper.addLivePlayBack(live.getId(),thread.getFilePath());
        //开启线程
        thread.start();
    }


    /**
     * 结束直播 修改状态
     *
     * @param id
     * @param status
     */
    @Override
    public void startStatusById(Long id, String status) {
        Integer likeNum =(Integer) redisTemplate.boundHashOps("like").get(id);
        TbLive live = liveMapper.findOne(id);
        //结束录制
        endlive(live);
        live.setEndTime(new Date());
        // 获得两个时间的毫秒时间差异
        long diff = live.getEndTime().getTime() - live.getStartTime().getTime();
        // 计算差多少天
        long day = diff / (1000 * 24 * 60 * 60);
        // 计算差多少小时
        long hour = diff % (1000 * 24 * 60 * 60) / (1000 * 60 * 60);
        // 计算差多少分钟
        long min = diff % (1000 * 24 * 60 * 60) % (1000 * 60 * 60) / (1000 * 60);
        // 计算差多少秒//输出结果
        String time = day + "天" + hour + "小时" + min + "分钟";
        live.setLiveTime(time);
        live.setStatus(status);
        live.setLikeNum(likeNum);
        liveMapper.startStatusById(live);
        redisTemplate.delete("like");

    }

    /**
     * 关闭直播录制
     * @param live
     */
    @Async
    public void endlive(TbLive live){
        //获取该线程中的所有的线程
        Map<Thread, StackTraceElement[]> allThread = Thread.getAllStackTraces();
        //
        List<Thread> ss = allThread.keySet().stream().collect(Collectors.toList());
        for(Thread a:ss){
            try {
                //找到线程名称为 live.getBrokerName()的线程并给他停掉
                System.out.println(a.getName()+"线程");
                System.out.println(live.getBrokerName()+"名称");
                if (live.getBrokerName().equals(a.getName())) {
                    //如果需要找到该线程,并且是在停止该线程之后才能进行其他的操作的话,需要用interrupt停掉之后,再执行此时的线程,所以还需要将当前的线程join到aaa2停掉之后
//                    a.interrupt();
//                    a.join();
                    //stop 线程仅仅是为了展示效果,不推荐这样直接关闭
                    a.stop();
                }
            }catch (Exception e){
                System.out.println("异常");
            }
        }
        //重新设置该线程的名称
        Thread.currentThread().setName(live.getBrokerName());

    }

}
